import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";

// 上传目录
const uploadDir = path.resolve("./uploads"); //从“当前工作目录（cwd）”出发，拼出 uploads 目录的绝对路径。
const dbFile = path.resolve("./uploads/hash_db.json"); // 用于 hash 秒传索引

//始终以当前 JS 文件所在目录为基准，向上一级找到 uploads 目录。
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const UPLOAD_DIR = path.resolve(__dirname, "../uploads");

if (!fs.existsSync(uploadDir)) fs.mkdirSync(uploadDir);
if (!fs.existsSync(dbFile)) fs.writeFileSync(dbFile, JSON.stringify({}));

// 单图上传（用于 el-upload 图片）
export const uploadImage = async (req, res) => {
  try {
    const file = req.file;
    if (!file) return res.status(400).json({ message: "未检测到上传文件" });

    const ext = path.extname(file.originalname);
    const filename = `${Date.now()}_${Math.random()
      .toString(36)
      .slice(2)}${ext}`;
    const filePath = path.join(UPLOAD_DIR, filename);

    // 将内存中的 buffer 写入文件
    fs.writeFileSync(filePath, file.buffer);

    // 返回可访问的 URL（前端访问 /uploads/xxx.jpg）
    const fullUrl = `${req.protocol}://${req.get("host")}/uploads/${filename}`;
    res.json({ url: fullUrl });
  } catch (err) {
    console.error("❌ 上传图片失败:", err);
    res.status(500).json({ message: "上传图片失败" });
  }
};

function getDB() {
  return JSON.parse(fs.readFileSync(dbFile, "utf-8"));
}
function setDB(db) {
  fs.writeFileSync(dbFile, JSON.stringify(db));
}
function saveHashMap(hash, filename, url) {
  const db = getDB();
  db[`${hash}_${filename}`] = url;
  setDB(db);
}
function getHashMap(hash, filename) {
  const db = getDB();
  return db[`${hash}_${filename}`];
}

// 新增：hash 秒传检测
export const fastUpload = (req, res) => {
  const { hash, filename } = req.body;
  const url = getHashMap(hash, filename);
  if (url) {
    res.json({ exists: true, url });
  } else {
    res.json({ exists: false });
  }
};

// 获取分片存储目录，保证 hash+filename 唯一
function getChunkDir(hash, filename) {
  return path.join(uploadDir, `${hash}-${filename}`);
}

// 1. 查询已上传分片
export const getUploadedChunks = (req, res) => {
  const { hash, filename } = req.query;
  const chunkDir = getChunkDir(hash, filename);
  let uploaded = [];
  if (fs.existsSync(chunkDir)) {
    uploaded = fs
      .readdirSync(chunkDir)
      .map((name) => parseInt(name))
      .filter((i) => !isNaN(i));
  }
  res.json({ uploaded });
};

// 2. 上传分片
export const uploadChunk = (req, res) => {
  const { filename, index, hash } = req.body;
  if (!hash) return res.status(400).json({ msg: "缺少hash" });
  // 创建以文件名为名的分片目录
  const chunkDir = getChunkDir(hash, filename);
  if (!fs.existsSync(chunkDir)) fs.mkdirSync(chunkDir);
  // 构建分片文件路径
  const chunkPath = path.join(chunkDir, String(index));
  // 将分片数据写入文件
  fs.writeFileSync(chunkPath, req.file.buffer);
  res.json({ success: true, msg: `分片${index}上传成功` });
};

// 3. 合并分片,记录hash
export const mergeChunks = (req, res) => {
  const { filename, total, hash } = req.body;
  // 设置路径
  const chunkDir = getChunkDir(hash, filename);
  const filePath = path.join(uploadDir, `${Date.now()}-${filename}`); // 防冲突

  if (!fs.existsSync(chunkDir)) {
    return res.status(400).json({ msg: "分片目录不存在" });
  }
  // 创建文件写入流
  const writeStream = fs.createWriteStream(filePath);
  for (let i = 0; i < total; i++) {
    const chunkPath = path.join(chunkDir, String(i));
    if (!fs.existsSync(chunkPath)) {
      writeStream.end();
      return res.status(400).json({ msg: `分片${i}缺失，无法合并` });
    }
    const data = fs.readFileSync(chunkPath);
    writeStream.write(data);
    fs.unlinkSync(chunkPath);
  }
  //结束写入流
  writeStream.end();
  fs.rmdirSync(chunkDir);

  // 合并后记录 hash 对应的文件 url
  const url = `/uploads/${path.basename(filePath)}`;
  saveHashMap(hash, filename, url);

  res.json({
    success: true,
    url: `/uploads/${path.basename(filePath)}`,
    msg: "合并成功",
  });
};
